package com.weiquan.controller;

import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.weiquan.common.Result;
import com.weiquan.dto.AdminCreateRequest;
import com.weiquan.dto.AdminLoginRequest;
import com.weiquan.dto.AdminUpdateRequest;
import com.weiquan.service.SysAdminService;
import com.weiquan.vo.AdminInfoVO;
import com.weiquan.vo.AdminLoginResponse;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.tags.Tag;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletRequest;
import javax.validation.Valid;
import javax.validation.constraints.NotEmpty;
import javax.validation.constraints.NotNull;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * 管理员控制器
 */
@Slf4j
@RestController
@RequestMapping("/api/admin")
@Tag(name = "管理员管理", description = "管理员登录、管理等相关接口")
@Validated
public class AdminController {

    @Autowired
    private SysAdminService adminService;

    /**
     * 管理员登录
     */
    @PostMapping("/login")
    @Operation(summary = "管理员登录", description = "管理员账号密码登录")
    public Result<AdminLoginResponse> login(
            @Valid @RequestBody AdminLoginRequest request,
            HttpServletRequest httpRequest) {
        
        String clientIp = getClientIp(httpRequest);
        
        log.info("管理员登录请求，用户名：{}，IP：{}", request.getUsername(), clientIp);
        
        AdminLoginResponse response = adminService.login(request, clientIp);
        
        return Result.success(response);
    }

    /**
     * 管理员登出
     */
    @PostMapping("/logout")
    @Operation(summary = "管理员登出", description = "管理员退出登录")
    public Result<Void> logout(HttpServletRequest request) {
        
        String token = request.getHeader("Authorization");
        if (token != null && token.startsWith("Bearer ")) {
            token = token.substring(7);
        }
        
        boolean success = adminService.logout(token);
        
        if (success) {
            return Result.success();
        } else {
            return Result.error("登出失败");
        }
    }

    /**
     * 获取当前管理员信息
     */
    @GetMapping("/info")
    @Operation(summary = "获取管理员信息", description = "获取当前登录管理员的详细信息")
    public Result<AdminInfoVO> getAdminInfo(HttpServletRequest request) {
        
        Long adminId = (Long) request.getAttribute("userId");
        
        AdminInfoVO adminInfo = adminService.getAdminInfo(adminId);
        
        return Result.success(adminInfo);
    }

    /**
     * 创建管理员
     */
    @PostMapping("/create")
    @Operation(summary = "创建管理员", description = "创建新的管理员账号")
    public Result<Void> createAdmin(
            @Valid @RequestBody AdminCreateRequest request,
            HttpServletRequest httpRequest) {
        
        Long createBy = (Long) httpRequest.getAttribute("userId");
        
        log.info("创建管理员请求，用户名：{}，创建者：{}", request.getUsername(), createBy);
        
        boolean success = adminService.createAdmin(request, createBy);
        
        if (success) {
            return Result.success();
        } else {
            return Result.error("创建管理员失败");
        }
    }

    /**
     * 更新管理员信息
     */
    @PutMapping("/{adminId}")
    @Operation(summary = "更新管理员信息", description = "更新指定管理员的信息")
    public Result<Void> updateAdmin(
            @Parameter(description = "管理员ID") @PathVariable @NotNull Long adminId,
            @Valid @RequestBody AdminUpdateRequest request,
            HttpServletRequest httpRequest) {
        
        Long updateBy = (Long) httpRequest.getAttribute("userId");
        
        log.info("更新管理员请求，管理员ID：{}，更新者：{}", adminId, updateBy);
        
        boolean success = adminService.updateAdmin(adminId, request, updateBy);
        
        if (success) {
            return Result.success();
        } else {
            return Result.error("更新管理员失败");
        }
    }

    /**
     * 删除管理员
     */
    @DeleteMapping("/{adminId}")
    @Operation(summary = "删除管理员", description = "删除指定的管理员")
    public Result<Void> deleteAdmin(
            @Parameter(description = "管理员ID") @PathVariable @NotNull Long adminId,
            HttpServletRequest request) {
        
        Long deleteBy = (Long) request.getAttribute("userId");
        
        log.info("删除管理员请求，管理员ID：{}，删除者：{}", adminId, deleteBy);
        
        boolean success = adminService.deleteAdmin(adminId, deleteBy);
        
        if (success) {
            return Result.success();
        } else {
            return Result.error("删除管理员失败");
        }
    }

    /**
     * 批量删除管理员
     */
    @DeleteMapping("/batch")
    @Operation(summary = "批量删除管理员", description = "批量删除多个管理员")
    public Result<Void> batchDeleteAdmin(
            @Parameter(description = "管理员ID列表") @RequestBody @NotEmpty List<Long> adminIds,
            HttpServletRequest request) {
        
        Long deleteBy = (Long) request.getAttribute("userId");
        
        log.info("批量删除管理员请求，数量：{}，删除者：{}", adminIds.size(), deleteBy);
        
        boolean success = adminService.batchDeleteAdmin(adminIds, deleteBy);
        
        if (success) {
            return Result.success();
        } else {
            return Result.error("批量删除管理员失败");
        }
    }

    /**
     * 更新管理员状态
     */
    @PutMapping("/{adminId}/status")
    @Operation(summary = "更新管理员状态", description = "启用或禁用管理员")
    public Result<Void> updateAdminStatus(
            @Parameter(description = "管理员ID") @PathVariable @NotNull Long adminId,
            @Parameter(description = "状态") @RequestParam @NotNull Integer status,
            HttpServletRequest request) {
        
        Long updateBy = (Long) request.getAttribute("userId");
        
        log.info("更新管理员状态请求，管理员ID：{}，状态：{}，更新者：{}", adminId, status, updateBy);
        
        boolean success = adminService.updateAdminStatus(adminId, status, updateBy);
        
        if (success) {
            return Result.success();
        } else {
            return Result.error("更新管理员状态失败");
        }
    }

    /**
     * 批量更新管理员状态
     */
    @PutMapping("/batch/status")
    @Operation(summary = "批量更新管理员状态", description = "批量启用或禁用管理员")
    public Result<Void> batchUpdateAdminStatus(
            @Parameter(description = "管理员ID列表") @RequestParam @NotEmpty List<Long> adminIds,
            @Parameter(description = "状态") @RequestParam @NotNull Integer status,
            HttpServletRequest request) {
        
        Long updateBy = (Long) request.getAttribute("userId");
        
        log.info("批量更新管理员状态请求，数量：{}，状态：{}，更新者：{}", adminIds.size(), status, updateBy);
        
        boolean success = adminService.batchUpdateAdminStatus(adminIds, status, updateBy);
        
        if (success) {
            return Result.success();
        } else {
            return Result.error("批量更新管理员状态失败");
        }
    }

    /**
     * 重置管理员密码
     */
    @PutMapping("/{adminId}/reset-password")
    @Operation(summary = "重置管理员密码", description = "重置指定管理员的密码")
    public Result<Void> resetPassword(
            @Parameter(description = "管理员ID") @PathVariable @NotNull Long adminId,
            @Parameter(description = "新密码") @RequestParam String newPassword,
            HttpServletRequest request) {
        
        Long updateBy = (Long) request.getAttribute("userId");
        
        log.info("重置管理员密码请求，管理员ID：{}，重置者：{}", adminId, updateBy);
        
        boolean success = adminService.resetPassword(adminId, newPassword, updateBy);
        
        if (success) {
            return Result.success();
        } else {
            return Result.error("重置密码失败");
        }
    }

    /**
     * 修改管理员密码
     */
    @PutMapping("/change-password")
    @Operation(summary = "修改管理员密码", description = "管理员修改自己的密码")
    public Result<Void> changePassword(
            @Parameter(description = "旧密码") @RequestParam String oldPassword,
            @Parameter(description = "新密码") @RequestParam String newPassword,
            HttpServletRequest request) {
        
        Long adminId = (Long) request.getAttribute("userId");
        
        log.info("管理员修改密码请求，管理员ID：{}", adminId);
        
        boolean success = adminService.changePassword(adminId, oldPassword, newPassword);
        
        if (success) {
            return Result.success();
        } else {
            return Result.error("修改密码失败");
        }
    }

    /**
     * 分页查询管理员列表
     */
    @GetMapping("/list")
    @Operation(summary = "分页查询管理员列表", description = "分页获取管理员列表")
    public Result<Page<AdminInfoVO>> getAdminList(
            @Parameter(description = "页码") @RequestParam(defaultValue = "1") int pageNum,
            @Parameter(description = "页大小") @RequestParam(defaultValue = "10") int pageSize,
            @Parameter(description = "搜索关键词") @RequestParam(required = false) String keyword,
            @Parameter(description = "角色") @RequestParam(required = false) Integer role,
            @Parameter(description = "状态") @RequestParam(required = false) Integer status) {
        
        Page<AdminInfoVO> adminPage = adminService.getAdminList(pageNum, pageSize, keyword, role, status);
        
        return Result.success(adminPage);
    }

    /**
     * 根据角色查询管理员
     */
    @GetMapping("/by-role")
    @Operation(summary = "根据角色查询管理员", description = "获取指定角色的管理员列表")
    public Result<List<AdminInfoVO>> getAdminsByRole(
            @Parameter(description = "角色") @RequestParam @NotNull Integer role) {
        
        List<AdminInfoVO> adminList = adminService.getAdminsByRole(role);
        
        return Result.success(adminList);
    }

    /**
     * 检查用户名是否存在
     */
    @GetMapping("/check-username")
    @Operation(summary = "检查用户名是否存在", description = "验证用户名是否已被使用")
    public Result<Map<String, Object>> checkUsernameExists(
            @Parameter(description = "用户名") @RequestParam String username,
            @Parameter(description = "排除的管理员ID") @RequestParam(required = false) Long excludeId) {
        
        boolean exists = adminService.checkUsernameExists(username, excludeId);
        
        Map<String, Object> result = new HashMap<>();
        result.put("exists", exists);
        result.put("message", exists ? "用户名已存在" : "用户名可用");
        
        return Result.success(result);
    }

    /**
     * 检查手机号是否存在
     */
    @GetMapping("/check-phone")
    @Operation(summary = "检查手机号是否存在", description = "验证手机号是否已被使用")
    public Result<Map<String, Object>> checkPhoneExists(
            @Parameter(description = "手机号") @RequestParam String phoneNumber,
            @Parameter(description = "排除的管理员ID") @RequestParam(required = false) Long excludeId) {
        
        boolean exists = adminService.checkPhoneExists(phoneNumber, excludeId);
        
        Map<String, Object> result = new HashMap<>();
        result.put("exists", exists);
        result.put("message", exists ? "手机号已存在" : "手机号可用");
        
        return Result.success(result);
    }

    /**
     * 检查邮箱是否存在
     */
    @GetMapping("/check-email")
    @Operation(summary = "检查邮箱是否存在", description = "验证邮箱是否已被使用")
    public Result<Map<String, Object>> checkEmailExists(
            @Parameter(description = "邮箱") @RequestParam String email,
            @Parameter(description = "排除的管理员ID") @RequestParam(required = false) Long excludeId) {
        
        boolean exists = adminService.checkEmailExists(email, excludeId);
        
        Map<String, Object> result = new HashMap<>();
        result.put("exists", exists);
        result.put("message", exists ? "邮箱已存在" : "邮箱可用");
        
        return Result.success(result);
    }

    /**
     * 获取管理员统计信息
     */
    @GetMapping("/statistics")
    @Operation(summary = "获取管理员统计信息", description = "获取管理员相关的统计数据")
    public Result<Map<String, Object>> getAdminStatistics() {
        
        Map<String, Object> statistics = adminService.getAdminStatistics();
        
        return Result.success(statistics);
    }

    /**
     * 获取管理员登录统计
     */
    @GetMapping("/login-statistics")
    @Operation(summary = "获取管理员登录统计", description = "获取管理员登录的统计数据")
    public Result<List<Map<String, Object>>> getLoginStatistics(
            @Parameter(description = "开始日期") @RequestParam String startDate,
            @Parameter(description = "结束日期") @RequestParam String endDate) {
        
        List<Map<String, Object>> statistics = adminService.getLoginStatistics(startDate, endDate);
        
        return Result.success(statistics);
    }

    /**
     * 获取最近登录的管理员
     */
    @GetMapping("/recent-login")
    @Operation(summary = "获取最近登录的管理员", description = "获取最近登录的管理员列表")
    public Result<List<AdminInfoVO>> getRecentLoginAdmins(
            @Parameter(description = "数量限制") @RequestParam(defaultValue = "10") int limit) {
        
        List<AdminInfoVO> adminList = adminService.getRecentLoginAdmins(limit);
        
        return Result.success(adminList);
    }

    /**
     * 检查管理员权限
     */
    @GetMapping("/check-permission")
    @Operation(summary = "检查管理员权限", description = "检查当前管理员是否有指定权限")
    public Result<Map<String, Object>> checkPermission(
            @Parameter(description = "权限标识") @RequestParam String permission,
            HttpServletRequest request) {
        
        Long adminId = (Long) request.getAttribute("userId");
        
        boolean hasPermission = adminService.hasPermission(adminId, permission);
        
        Map<String, Object> result = new HashMap<>();
        result.put("hasPermission", hasPermission);
        result.put("permission", permission);
        
        return Result.success(result);
    }

    /**
     * 更新管理员权限
     */
    @PutMapping("/{adminId}/permissions")
    @Operation(summary = "更新管理员权限", description = "更新指定管理员的权限列表")
    public Result<Void> updatePermissions(
            @Parameter(description = "管理员ID") @PathVariable @NotNull Long adminId,
            @Parameter(description = "权限列表") @RequestBody @NotEmpty List<String> permissions,
            HttpServletRequest request) {
        
        Long updateBy = (Long) request.getAttribute("userId");
        
        log.info("更新管理员权限请求，管理员ID：{}，权限数量：{}，更新者：{}", adminId, permissions.size(), updateBy);
        
        boolean success = adminService.updatePermissions(adminId, permissions, updateBy);
        
        if (success) {
            return Result.success();
        } else {
            return Result.error("更新权限失败");
        }
    }

    /**
     * 获取管理员权限列表
     */
    @GetMapping("/{adminId}/permissions")
    @Operation(summary = "获取管理员权限列表", description = "获取指定管理员的权限列表")
    public Result<List<String>> getAdminPermissions(
            @Parameter(description = "管理员ID") @PathVariable @NotNull Long adminId) {
        
        List<String> permissions = adminService.getAdminPermissions(adminId);
        
        return Result.success(permissions);
    }

    /**
     * 刷新Token
     */
    @PostMapping("/refresh-token")
    @Operation(summary = "刷新Token", description = "刷新管理员访问令牌")
    public Result<Map<String, Object>> refreshToken(HttpServletRequest request) {
        
        String token = request.getHeader("Authorization");
        if (token != null && token.startsWith("Bearer ")) {
            token = token.substring(7);
        }
        
        String newToken = adminService.refreshToken(token);
        
        Map<String, Object> result = new HashMap<>();
        result.put("accessToken", newToken);
        result.put("tokenType", "Bearer");
        result.put("expiresIn", 24 * 60 * 60); // 1天
        
        return Result.success(result);
    }

    /**
     * 获取客户端IP地址
     */
    private String getClientIp(HttpServletRequest request) {
        String xForwardedFor = request.getHeader("X-Forwarded-For");
        if (xForwardedFor != null && !xForwardedFor.isEmpty() && !"unknown".equalsIgnoreCase(xForwardedFor)) {
            return xForwardedFor.split(",")[0];
        }
        
        String xRealIp = request.getHeader("X-Real-IP");
        if (xRealIp != null && !xRealIp.isEmpty() && !"unknown".equalsIgnoreCase(xRealIp)) {
            return xRealIp;
        }
        
        return request.getRemoteAddr();
    }
}